package com.jf.cloud.service.sysmanager.common.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件工具类
 * 
 * @author 程伟平 创建时间：2012-02-08 14:15:17
 */
public final class FileUtil {

	private static final Log log = LogFactory.getLog(FileUtil.class);

	public static final List<String> fileSuffixList = new ArrayList<String>();
	
	public static final List<String> SuffixList = new ArrayList<String>();

	// System support picture suffixs
	static {
		fileSuffixList.add(".jpg");
		fileSuffixList.add(".jpeg");
		fileSuffixList.add(".png");
		fileSuffixList.add(".gif");
		fileSuffixList.add(".bmp");
	}
	// System support picture suffixs
	static {
		SuffixList.add("jpg");
		SuffixList.add("jpeg");
		SuffixList.add("png");
		SuffixList.add("gif");
		SuffixList.add("bmp");
	}

	/**
	 * 创建目录
	 * 
	 * @param destDirName 目标目录名
	 */
	public static void createDir(String destDirName) {
		File dir = new File(destDirName);
		if (!dir.exists()) {
			if (!destDirName.endsWith(File.separator)) {
				destDirName = destDirName + File.separator;
			}
			// 创建目录
			if (dir.mkdirs()) {
				log.info("创建目录" + destDirName + "成功！");
			}
		}
	}

	/**
	 * 复制单个文件
	 * 
	 * @param srcFileName 待复制的文件名
	 * @param descFileName 目标文件名
	 * @param overlay 如果目标文件存在，是否覆盖
	 * @return 如果复制成功返回true，否则返回false
	 */
	public static boolean copyFile(String srcFileName, String destFileName, boolean overlay) {
		File srcFile = new File(srcFileName);

		// 判断源文件是否存在
		if (!srcFile.exists()) {
			log.error("源文件：" + srcFileName + "不存在！");
			return false;
		} else if (!srcFile.isFile()) {
			log.error("复制文件失败，源文件：" + srcFileName + "不是一个文件！");
			return false;
		}

		// 判断目标文件是否存在
		File destFile = new File(destFileName);
		if (destFile.exists()) {
			// 如果目标文件存在并允许覆盖
			if (overlay) {
				// 删除已经存在的目标文件，无论目标文件是目录还是单个文件
				new File(destFileName).delete();
			}
		} else {
			// 如果目标文件所在目录不存在，则创建目录
			if (!destFile.getParentFile().exists()) {
				// 目标文件所在目录不存在
				if (!destFile.getParentFile().mkdirs()) {
					// 复制文件失败：创建目标文件所在目录失败
					return false;
				}
			}
		}

		// 复制文件
		int byteread = 0; // 读取的字节数
		InputStream in = null;
		OutputStream out = null;

		try {
			in = new FileInputStream(srcFile);
			out = new FileOutputStream(destFile);
			byte[] buffer = new byte[1024];

			while ((byteread = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteread);
			}
			return true;
		} catch (FileNotFoundException e) {
			return false;
		} catch (IOException e) {
			return false;
		} finally {
			try {
				if (out != null)
					out.close();
				if (in != null)
					in.close();
			} catch (IOException e) {
			}
		}
	}

	/**
	 * 复制整个目录的内容
	 * 
	 * @param srcDirName 待复制目录的目录名
	 * @param destDirName 目标目录名
	 * @param overlay 如果目标目录存在，是否覆盖
	 * @return 如果复制成功返回true，否则返回false
	 */
	public static boolean copyDir(String srcDirName, String destDirName, boolean overlay) {
		// 判断源目录是否存在
		File srcDir = new File(srcDirName);
		if (!srcDir.exists()) {
			log.error("复制目录失败：源目录" + srcDirName + "不存在！");
			return false;
		} else if (!srcDir.isDirectory()) {
			log.error("复制目录失败：" + srcDirName + "不是目录！");
			return false;
		}

		// 如果目标目录名不是以文件分隔符结尾，则加上文件分隔符
		if (!destDirName.endsWith(File.separator)) {
			destDirName = destDirName + File.separator;
		}
		File destDir = new File(destDirName);
		// 如果目标文件夹存在
		if (destDir.exists()) {
			// 如果允许覆盖则删除已存在的目标目录
			if (overlay) {
				new File(destDirName).delete();
			} else {
				log.error("复制目录失败：目的目录" + destDirName + "已存在！");
				return false;
			}
		} else {
			// 创建目的目录
			log.info("目的目录不存在，准备创建。。。");
			if (!destDir.mkdirs()) {
				log.info("复制目录失败：创建目的目录失败！");
				return false;
			}
		}

		boolean flag = true;
		File[] files = srcDir.listFiles();
		for (int i = 0; i < files.length; i++) {
			// 复制文件
			if (files[i].isFile()) {
				flag = FileUtil.copyFile(files[i].getAbsolutePath(), destDirName + files[i].getName(), overlay);
				if (!flag)
					break;
			} else if (files[i].isDirectory()) {
				flag = FileUtil.copyDir(files[i].getAbsolutePath(), destDirName + files[i].getName(), overlay);
				if (!flag)
					break;
			}
		}
		if (!flag) {
			log.error("复制目录" + srcDirName + "至" + destDirName + "失败！");
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 从流读取文件
	 * 
	 * @param savePath 保存文件的位置
	 * @param fileName 保存文件的名称
	 * @param in 源文件输入流
	 */
	public static boolean saveFile(String savePath, String fileName, InputStream in) throws Exception {
		boolean a = false;
		File saveFile = null;
		OutputStream out = null;
		if (savePath != null && fileName != null) {
			log.info("★★★★★开始上传文件★★★★★文件路径:" + savePath + " 文件名称:" + fileName);
			try {
				saveFile = new File(savePath);
				if (!saveFile.exists()) { // 不存在即创建此路劲
					saveFile.mkdir();
				}
				out = new FileOutputStream(savePath + fileName);
				byte[] by = new byte[in.available()]; // 限制大小为 2M 也可以从读取的文件取得大小
				int sumRead = 0;
				while ((sumRead = in.read(by)) != -1) { // 把读取的字符 放入数组by 返回读取的长度
					out.write(by, 0, sumRead); // 从数组中读出 0 到 sumRead长度的 字符
				}
				a = true;
			} catch (Exception e) {
				log.error("保存文件失败", e);
			} finally {
				out.flush();
				out.close();
				in.close();
			}
		} else {
			log.info("★★★★★★文件名称和路径不允许为空★★★★★★★★★");
		}
		return a;
	}

	/**
	 * 通过字节数组 保存文件
	 * 
	 * @param savePath 保存文件的位置
	 * @param fileName 保存文件的名称
	 * @param in 源文件 字节数组
	 */
	public static boolean saveFileByte(String savePath, String fileName, byte[] fileByte) throws Exception {
		boolean a = false;
		File saveFile = null;
		OutputStream out = null;
		if (savePath != null && fileName != null) {
			log.info("★★★★★开始上传文件★★★★★文件路径:" + savePath + " 文件名称:" + fileName);
			try {
				saveFile = new File(savePath);
				if (!saveFile.exists()) { // 不存在即创建此路劲
					createDir(savePath);
				}
				out = new FileOutputStream(savePath + fileName);
				out.write(fileByte); // 从数组中读出
				a = true;
			} catch (Exception e) {
				log.error("服务器上传文件保存失败=★★★★★★★★★===", e);
			} finally {
				out.flush();
				out.close();
			}
		} else {
			log.info("★★★★★★文件名称和路径不允许为空★★★★★★★★★");
		}
		return a;
	}

	/**
	 * 检查文件后缀 是否合法 TODO
	 * 
	 * @author ouyang 创建时间：Apr 17, 2012 9:42:57 AM
	 */
	public static boolean checkFileSuffix(String suffix) {
		if (suffix != null) {
			String verifyString = suffix;
			if (!suffix.contains(".")) {
				verifyString = "." + suffix;
			}
			verifyString = verifyString.toLowerCase();
			return fileSuffixList.contains(verifyString);
		}
		return false;
	}
	/**
	 * 获取 图片格式
	 */
	public static String getSuffix(String filePath) {
	    String rString ="";
		if(StringUtil.notNull(filePath)){
			for (int i = 0; i < SuffixList.size(); i++) {
				if(filePath.toLowerCase().contains(SuffixList.get(i))){
					return SuffixList.get(i);
				}
			}
		}
		return rString;
	}
	/**
	 * 删除文件 或者指定的目录
	 * @author ouyang 创建时间：Apr 18, 2012 10:28:17 AM
	 */
	public static boolean deleteFile(String fileFullPath) {
		// 判断目标文件是否存在
		File destFile = new File(fileFullPath);
		if (destFile.exists()) {
			// 删除已经存在的目标文件，无论目标文件是目录还是单个文件
			return new File(fileFullPath).delete();
		}
		return true;
	}
}
